/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/
#pragma once

#include <stdint.h>

struct kDataView;

class kImage;
class kResources;
class kStream;
class kEngine;
class kGraphics;

#include "kbase.h"
#include "kmath.h"
#include "keimageoptions.h"
#include "keimageformat.h"
#include "ksharedresources.h"
#include "kerror.h"

class kImage : public kBase, public kSharedResource<std::tstring, kGraphics> {
	friend class kSharedResourcesBase<kImage>;
	friend class kSharedResources<kImage>;

private:
	static const bool AllowShare = true;
	static kImage* createShared(Container* container, const Key& key);
	static void destroyShared(Container* container, kImage* resource);

	virtual void doProcess(kRect* region, bool readonly, std::function<void (const kVec2i&, kColor&)> lambda) const = 0;

protected:
	kVec2i _size;
	keImageOptions _options;
	kEngine* _engine;

	inline kImage(kEngine* engine) {
		_size.x = 0;
		_size.y = 0;
		_options = keImage_None;
		_engine = engine;
	}
public:
	inline kEngine* getEngine() const {
		return _engine;
	}
	inline const kVec2i& getSize() const {
		return _size;
	}
	inline keImageOptions getOptions() const {
		return _options;
	}
	virtual void save(kStream* stream, keImageFormat format) const = 0;
	void save(const std::tstring& uri, keImageFormat format) const;
	inline void process(kRect* region, bool readonly, std::function<void (const kVec2i&, kColor&)> lambda) const {
		if (!readonly)
			throw kError(_T("Cannot modify image"));

		doProcess(region, readonly, lambda);
	}
	inline void process(kRect* region, bool readonly, std::function<void (const kVec2i&, kColor&)> lambda) {
		doProcess(region, readonly, lambda);
	}
};
